const AElf = require('aelf-sdk');
const aelf = new AElf(new AElf.providers.HttpProvider('http://127.0.0.1:1235'));
const PkManageModule = require('../models/private_key_manage');
const { param } = require('../routes/main_frame');

const tokenContractName = 'AElf.ContractNames.Token';
const CRAddress = '2LUmicHyH4RXrMjG4beDwuDsiWJESyLkgkwPdGTR8kahRzq5XS';

class AElfModule {
    constructor() {
    }

    check_cr_state(param, CRT_id, cb) {
        param.contract.getAllInfo.call(CRT_id)
            .then(result => {
                console.log(result)
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
        
    }

    check_chain_state(cb) {
        if (!aelf.isConnected()) {
            console.log('Blockchain Node is not running.');
            let state = false;
            cb(state);
        }
        else {
            let state = true;
            cb(state);
        }
    }

    create_wallet() {
        const newWallet = AElf.wallet.createNewWallet();
        return newWallet.privateKey;
    }

    load_wallet(priKey, cb) {
        var wallet = AElf.wallet.getWalletByPrivateKey(priKey);
        if (wallet == 'undefined') {
            console.log('wallet not exist');
        }
        else {
            console.log('load successful');
            this.wallet = wallet;
        }
        cb(wallet);

    }

    load_contract(flag, cb) {
        

        if (flag == false) {
            let tokenContractAddress;
            let tokenContract;
            (async () => {
                // get chain status
                const chainStatus = await aelf.chain.getChainStatus();
                // get genesis contract address
                const GenesisContractAddress = chainStatus.GenesisContractAddress;
                // get genesis contract instance
                const zeroContract = await aelf.chain.contractAt(GenesisContractAddress, this.wallet);
                // Get contract address by the read only method `GetContractAddressByName` of genesis contract
                tokenContractAddress = await zeroContract.GetContractAddressByName.call(AElf.utils.sha256(tokenContractName));

                tokenContract = await aelf.chain.contractAt(tokenContractAddress, this.wallet);

                cb({
                    wallet: this.wallet,
                    contract: tokenContract
                })
            })()
        }
        else {
            let CRContract;
            (async () => {
                // get chain status
                CRContract = await aelf.chain.contractAt(CRAddress, this.wallet);
                cb({
                    wallet: this.wallet,
                    contract: CRContract
                })
            })()
        }
    }

    register(param) {
        param.contract.CR_Register(param.wallet.address)
            .then(result => {
                console.log(result);
                return result;
            })
            .catch(err => {
                console.log(err);
            });

    }

    login(param) {
        param.contract.CR_Login(param.wallet.address)
            .then(result => {
                console.log(result);
                return result;
            })
            .catch(err => {
                console.log(err);
            });
    }

    getBalance(param, cb){
        param.contract.GetBalance.call({
            symbol: 'ELF',
            owner:param.wallet.address
        })
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                
                console.log(err);
            });
    }

    getAllCRTs(param, cb){
        param.contract.getAllCRTs.call(param.wallet.address)
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }

    logout(param) {
        param.contract.CR_Logout(param.wallet.address)
            .then(result => {
                return result;
            })
            .catch(err => {
                console.log(err);
            });
    }

    approve(param, amount, cb) {
        param.contract.Approve({
            symbol: 'ELF',
            spender: CRAddress,
            amount: amount
        })
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }

    CR_Upload(param, creator, content, cb) {
        PkManageModule.get_priKey_by_user(creator, (creator) => {
            console.log(creator);
            var wallet = AElf.wallet.getWalletByPrivateKey(creator.priKey);
            if (wallet == 'undefined') {
                console.log('wallet not exist');
            }
            else {
                param.contract.CR_Upload({
                    CRT_Creator: wallet.address,
                    CRT_Owner: param.wallet.address,
                    CRT_Content: content,
                    CRT_Status: 0
                })
                    .then(result => {
                        console.log(result);
                        cb(result);
                    })
                    .catch(err => {
                        console.log(err);
                    });

            }
        })

    }

    Recharge(param, receiver, amount) {
        PkManageModule.get_priKey_by_user(receiver, (rec_user) => {
            var wallet = AElf.wallet.getWalletByPrivateKey(rec_user.priKey);
            if (wallet == 'undefined') {
                console.log('wallet not exist');
            }
            else {
                param.contract.Approve({
                    symbol: 'ELF',
                    spender: param.contract.address,
                    amount: amount
                })
                .then((res)=>{
                    console.log(res);
                    param.contract.GetBalance.call({
                        symbol: 'ELF',
                        owner: param.contract.address,
                    })
                    .then((result) => {
                        param.contract.Transfer({
                            to: wallet.address,
                            amount: amount,
                            symbol: 'ELF',
                            memo: 'none'
                    })
                    .then(result => {
                        console.log(result);
                        param.contract.GetBalance.call({
                            symbol: 'ELF',
                            owner: wallet.address,
                        }).then((res)=>{
                            console.log(res)
                        })
                        return result;
                    })
                    .catch(err => {
                        console.log(err);
                    });
                })
                    
                })
            }
        })
    }

    CR_Transfer(param, buyer, price, id, cb){
        param.contract.CR_Transfer({
            CRT_ID: id,
            addr: buyer,
            price: price
        })
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }    

    CR_Plegde(param, buyer, p, id, time, cb){
        
        var input ={
            pledgee : buyer,
            pledger : param.wallet.address,
            price : p,
            CRT_ID : id,
            timeLimit : time,
            notice : "hello"
        }
        console.log(input)
        param.contract.CR_Pledge(input)
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }

    CR_Authorize(param, authorized, p, id, cb){
        var input ={
            CRT_ID: id,
            Price : p,
            addr: authorized
        }
        console.log(input)
        param.contract.CR_Authorize(input)
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }

    CR_UnAuthorize(param, authorized, id, cb){
        var input ={
            CRT_ID: id,
            Unauthorize: authorized
        }
        console.log(input)
        param.contract.CR_UnAuthorize(input)
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }

    CR_UnPledge(param, id, cb){
        console.log(id);
        param.contract.CR_UnPledge(id)
            .then(result => {
                console.log(result);
                cb(result);
            })
            .catch(err => {
                console.log(err);
            });
    }
}

module.exports = AElfModule;